package com.sean.community.comtroller;

import com.alibaba.fastjson.JSONObject;
import com.sean.community.annotation.LoginRequired;
import com.sean.community.entity.Message;
import com.sean.community.entity.Page;
import com.sean.community.entity.User;
import com.sean.community.service.MessageService;
import com.sean.community.service.UserService;
import com.sean.community.util.CommunityConstant;
import com.sean.community.util.CommunityUtil;
import com.sean.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.HtmlUtils;

import java.util.*;

@Controller
public class MessageController implements CommunityConstant {
    private MessageService messageService;
    private UserService userService;
    private HostHolder hostHolder;

    @Autowired
    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Autowired
    public void setHostHolder(HostHolder hostHolder) {
        this.hostHolder = hostHolder;
    }

    @LoginRequired
    @RequestMapping(path = "/letter/list", method = RequestMethod.GET)
    public String  getLetterList(Model model, Page page){
        User user = hostHolder.getUser();
        // 设置分页信息
        page.setPath("/letter/list");
        page.setLimit(5);
        page.setRows(messageService.findConversationsCount(user.getId()));
        // 会话列表
        List<Message> conversationList = messageService.findConversations(
                user.getId(), page.getOffset(), page.getLimit());
        List<Map<String, Object>> conversations = new ArrayList<>();
        if (conversationList != null) {
            for(Message message : conversationList){
                Map<String, Object> map = new HashMap<>();
                map.put("conversation", message);
                map.put("unreadCount", messageService.findLetterUnreadCount(user.getId(), message.getConversationId()));
                map.put("letterCount", messageService.findLetterCount(message.getConversationId()));
                // 找到另外一个用户
                if(message.getFromId() == user.getId()){
                    map.put("anotherUser", userService.findUserById(message.getToId()));
                }else{
                    map.put("anotherUser", userService.findUserById(message.getFromId()));
                }
                conversations.add(map);
            }
        }
        model.addAllAttributes(new ModelMap("conversations", conversations));
        // 总的未读消息数量
        int letterUnreadCount = messageService.findLetterUnreadCount(user.getId(), null);
        model.addAllAttributes(new ModelMap("letterUnreadCount", letterUnreadCount));
        int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null);
        model.addAllAttributes(new ModelMap("noticeUnreadCount", noticeUnreadCount));
        return "/site/letter";
    }

    @LoginRequired
    @RequestMapping(value = "/letter/detail/{conversationId}", method = RequestMethod.GET)
    public String getLetterDetail(@PathVariable("conversationId") String conversationId, Model model, Page page){
        User user = hostHolder.getUser();
        // 设置分页信息
        page.setPath("/letter/detail/" + conversationId);
        page.setLimit(5);
        page.setRows(messageService.findLetterCount(conversationId));
        List<Message> letterList = messageService.findLetters(conversationId, page.getOffset(), page.getLimit());
        List<Map<String, Object>> letters = new ArrayList<>();
        if (letterList != null) {
            for (Message letter : letterList){
                Map<String, Object> map = new HashMap<>();
                map.put("letter", letter);
                map.put("fromUser", userService.findUserById(letter.getFromId()));
                letters.add(map);
            }
        }
        model.addAllAttributes(new ModelMap("letters", letters));
        // 找到另外一个用户
        User letterTargetUser = getLetterTargetUser(conversationId);
        model.addAllAttributes(new ModelMap("targetUser", letterTargetUser));
        // 把未读改为已读
        List<Integer> unreadLetterIdList = getUnreadMessageIdList(letterList);
        if(!unreadLetterIdList.isEmpty()){
            messageService.readMessage(unreadLetterIdList);
        }
        return "/site/letter-detail";
    }

    /**
     * 获取未读私信 id
     * @param messageList 所有消息列表
     * @return 未读消息的 id
     */
    private List<Integer> getUnreadMessageIdList(List<Message> messageList){
        List<Integer> idList = new ArrayList<>();
        int currentUserId = hostHolder.getUser().getId();
        if(messageList != null){
            for (Message message : messageList){
                // 当前用户是消息的接收者，并且消息处于未读状态
                if(currentUserId == message.getToId() && message.getStatus() == MESSAGE_STATUS_UNREAD){
                    idList.add(message.getId());
                }
            }
        }
        return idList;
    }

    /**
     * 获取与当前登录用户私信的对象
     * @param conversationId 会话 id
     * @return 当前登录用户私信的对象
     */
    private User getLetterTargetUser(String conversationId){
        String[] str_ids = conversationId.split("_");
        try {
            int first_id = Integer.parseInt(str_ids[0]);
            int second_id = Integer.parseInt(str_ids[1]);
            User user = hostHolder.getUser();
            if(user.getId() == first_id){
                return userService.findUserById(second_id);
            }else{
                return userService.findUserById(first_id);
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping(path = "/letter/send", method = RequestMethod.POST)
    @ResponseBody
    public String sendLetter(String toName, String content){
        User targetUser = userService.findUserByUsername(toName);
        if(targetUser == null){
            return CommunityUtil.getJSONString(404, "目标用户不存在！");
        }
        Message message = new Message();
        message.setFromId(hostHolder.getUser().getId());
        message.setToId(targetUser.getId());
        if(message.getFromId() < message.getToId()){
            message.setConversationId(message.getFromId() + "_" + message.getToId());
        }else{
            message.setConversationId(message.getToId() + "_" + message.getFromId());
        }
        message.setContent(content);
        message.setStatus(MESSAGE_STATUS_UNREAD);
        message.setCreateTime(new Date());
        messageService.addMessage(message);
        return CommunityUtil.getJSONString(200, "发送成功！");
    }

    @SuppressWarnings("all")
    @RequestMapping(path = "/notice/list", method = RequestMethod.GET)
    public String getNoticeList(Model model){
        User user = hostHolder.getUser();
        // 查询评论类的通知
        Message commentNotice = messageService.findLatestNotice(user.getId(), TOPIC_COMMENT);
        if(commentNotice != null){
            Map<String, Object> commentNoticeVo = new HashMap<>();
            commentNoticeVo.put("commentNotice", commentNotice);
            String content = HtmlUtils.htmlUnescape(commentNotice.getContent());
            Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);
            commentNoticeVo.put("eventUser", userService.findUserById((int)data.get("userId")));    // 触发通知的用户
            commentNoticeVo.put("entityType", data.get("entityType"));    // 触发通知的实体类型
            commentNoticeVo.put("entityId", data.get("entityId"));        // 触发通知的实体 id
            commentNoticeVo.put("discussPostId", data.get("discussPostId"));  // 触发通知的帖子 id
            // 查询评论类通知的数量
            int noticeCount = messageService.findNoticeCount(user.getId(), TOPIC_COMMENT);
            commentNoticeVo.put("noticeCount", noticeCount);
            // 查询评论类通知的未读数量
            int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), TOPIC_COMMENT);
            commentNoticeVo.put("unreadCount", noticeUnreadCount);
            model.addAllAttributes(new ModelMap("commentNoticeVo", commentNoticeVo));
        }

        // 查询点赞类的通知
        Message likeNotice = messageService.findLatestNotice(user.getId(), TOPIC_LIKE);
        if(likeNotice != null){
            Map<String, Object> likeNoticeVo = new HashMap<>();
            likeNoticeVo.put("likeNotice", likeNotice);
            String content = HtmlUtils.htmlUnescape(likeNotice.getContent());
            Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);
            likeNoticeVo.put("eventUser", userService.findUserById((int)data.get("userId")));    // 触发通知的用户
            likeNoticeVo.put("entityType", data.get("entityType"));    // 触发通知的实体类型
            likeNoticeVo.put("entityId", data.get("entityId"));        // 触发通知的实体 id
            likeNoticeVo.put("discussPostId", data.get("discussPostId"));  // 触发通知的帖子 id
            // 查询点赞类通知的数量
            int noticeCount = messageService.findNoticeCount(user.getId(), TOPIC_LIKE);
            likeNoticeVo.put("noticeCount", noticeCount);
            // 查询点赞类通知的未读数量
            int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), TOPIC_LIKE);
            likeNoticeVo.put("unreadCount", noticeUnreadCount);
            model.addAllAttributes(new ModelMap("likeNoticeVo", likeNoticeVo));
        }

        // 查询关注类的通知
        Message followNotice = messageService.findLatestNotice(user.getId(), TOPIC_FOLLOW);
        if(followNotice != null){
            Map<String, Object> followNoticeVo = new HashMap<>();
            followNoticeVo.put("followNotice", followNotice);
            String content = HtmlUtils.htmlUnescape(followNotice.getContent());
            Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);
            followNoticeVo.put("eventUser", userService.findUserById((int)data.get("userId")));    // 触发通知的用户
            followNoticeVo.put("entityType", data.get("entityType"));    // 触发通知的实体类型
            followNoticeVo.put("entityId", data.get("entityId"));        // 触发通知的实体 id
            // 查询关注类通知的数量
            int noticeCount = messageService.findNoticeCount(user.getId(), TOPIC_FOLLOW);
            followNoticeVo.put("noticeCount", noticeCount);
            // 查询关注类通知的未读数量
            int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), TOPIC_FOLLOW);
            followNoticeVo.put("unreadCount", noticeUnreadCount);
            model.addAllAttributes(new ModelMap("followNoticeVo", followNoticeVo));
        }
        // 查询总的未读消息数量
        int letterUnreadCount = messageService.findLetterUnreadCount(user.getId(), null);
        int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null);
        model.addAllAttributes(new ModelMap("letterUnreadCount", letterUnreadCount));
        model.addAllAttributes(new ModelMap("noticeUnreadCount", noticeUnreadCount));
        return "/site/notice";
    }

    @SuppressWarnings("all")
    @RequestMapping(value = "/notice/detail/{topic}", method = RequestMethod.GET)
    public String getNoticeDetail(@PathVariable("topic") String topic, Page page, Model model){
        // 获取当前用户
        User user = hostHolder.getUser();
        // 设置分页信息
        page.setLimit(5);
        page.setRows(messageService.findNoticeCount(user.getId(), topic));
        page.setPath("/notice/detail/" + topic);
        // 查询详细列表
        List<Message> noticeList = messageService.findNotices(user.getId(), topic, page.getOffset(), page.getLimit());
        List<Map<String, Object>> noticeVoList = new ArrayList<>();
        if(noticeList != null){
            for(Message notice : noticeList){
                Map<String, Object> noticeVo = new HashMap<>();
                // 将通知放入 noticeVo
                noticeVo.put("notice", notice);
                // 将通知内容放入 noticeVo
                String content = HtmlUtils.htmlUnescape(notice.getContent());
                Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);
                noticeVo.put("user", userService.findUserById((int)data.get("userId"))); // 触发通知的用户
                noticeVo.put("entityType", data.get("entityType"));
                noticeVo.put("entityId", data.get("entityId"));
                noticeVo.put("discussPostId", data.get("discussPostId"));
                // 发通知的作者 System
                noticeVo.put("fromUser", userService.findUserById(notice.getFromId()));
                noticeVoList.add(noticeVo);
            }
        }
        model.addAllAttributes(new ModelMap("noticeVoList", noticeVoList));
        // 设置为已读
        List<Integer> unreadNoticeIdList = getUnreadMessageIdList(noticeList);
        if(!unreadNoticeIdList.isEmpty()){
            messageService.readMessage(unreadNoticeIdList);
        }
        return "/site/notice-detail";
    }
}
